import 'package:dio/dio.dart';
import 'package:fake_handwriting/Util.dart';
import 'package:fake_handwriting/http/bean/file_bean.dart';
import 'package:fake_handwriting/http/bean/master_bean.dart';
import 'package:fake_handwriting/http/bean/upload_bean.dart';
import 'package:shared_preferences/shared_preferences.dart';

class ResponseData {
  final int? code;
  final String? message;
  final dynamic data;

  ResponseData({this.code, this.message, this.data});
  ResponseData.fromJson(Map json): code = toInt(json['code']),
        message = json['message'] as String?,
        data = json['data'];
  Map tojson() {
    return {'code': code, 'message': message, 'data': data};
  }

  @override
  String toString() {
    return tojson().toString();
  }

  T? getTypedData<T>(T? Function(Map? map) creator) {
    var map = data as Map<String, dynamic>?;
    if (map == null) {
      return null;
    }
    return creator(map);
  }

  List<T?>? getTypedList<T>(T? Function(Map? map) creator) {
    List? list = data as List?;
    return toList(list, creator);
  }

  static List<T?>? toList<T>(List? mapList, T? Function(Map? map) creator) {
    if (mapList == null) {
      return null;
    }

    List<T?> ret = [];
    for (var m in mapList) {
      if (m == null) continue;
      var t = creator(m);
      ret.add(t);
    }

    return ret;
  }

  static int? toInt(dynamic data) {
    try {
      if (data == null) return null;
      if (data.runtimeType == int) return data;
      if (data.runtimeType == double) return (data as double).toInt();
      if (data.runtimeType == String) {
        String? string = (data as String?)?.trim();
        if (string == null || string.isEmpty) return null;

        return int.tryParse(string);
      }
    } catch (e, s) {}

    return null;
  }
}
class Http {
  // static const BASE_URL = "http://jimonik.vaiwan.cn/";
  static const BASE_URL = "http://117.50.162.33/";
  static Future<ResponseData> request({required String url, required Map<String, dynamic> params}) async {
    Util.println("_________________________________");
    Util.println("url:$BASE_URL$url");
    Util.println("param:$params");
    Util.println("_________________________________");
    var sp = await SharedPreferences.getInstance();
    var token=sp.getString("token")??"";
    Util.println("_____token:$token");
    var response = await Dio().request(
      "$BASE_URL$url",
      data: FormData.fromMap(params),
      options: Options(
        method: "POST",
        contentType: "application/json",
        headers: {
          "token":token
        }
      ),
    );
    var res = ResponseData.fromJson(response.data);
    if (res.code == 200) {
      return res;
    } else {
      Util.toast(res.message.toString());
      throw Exception("请求错误");
    }
  }

  static Future<String> register(String email, String password) async {
    var response = await request(url: "user/register/", params: {
      "email": email,
      "password": password,
    });
    return response.data as String;
  }

  static Future<String> sendEmail(String email) async {

    var response = await request(url: "user/sendEmail/", params: {"email": email});
    return response.data as String;
  }

  static Future<String> reset_password(String email, String password) async {
    var response = await request(url: "user/reset_password/", params: {
      "email": email,
      "password": password,
    });
    return response.data as String;
  }

  static Future<String> login(String email, String password) async {
    var response = await request(url: "user/login/", params: {
      "email": email,
      "password": password,
    });
    return response.data as String;
  }

  static update_profile(String nickname) async {
    var response = await request(url: "user/update_profile/", params: {
      "nickname": nickname,
    });
    await Util.loginSuccess(response.data as String);
  }

  static Future<UploadBean?> upload(String path, String name, String type) async {
    var response = await request(url: "file/upload/", params: {
      "file": await MultipartFile.fromFile(path, filename: name),
      "type": type,
    });
    return response.getTypedData((map) => UploadBean.fromJson(map));
  }

  static Future<List<FileBean?>?> get_files(String type) async {
    var response = await request(
        url: "file/get_files/",
        params: {"type": type});
    return response.getTypedList<FileBean>((map) => FileBean.fromJson(map));
  }

  static Future<List> delete_file(String id) async {
    var response =
        await request(url: "file/delete_file/", params: {"id": id});
    return response.data as List;
  }
  static delete_account() async {
    var r=await request(url: "user/delete_account/", params: {});
    return r.data as String;
  }

  static Future<String> make({
    required String image_id,
    required String content,
    required String font_id,
    required String fontSize,
    required String fontCount,
    required String fontColor,
    required String rowSpacing,
    required String start_x,
    required String start_y,
    required String line,
    required String type,
    required String title,
  }) async {
    var r=await request(url: "master/make/", params: {
      "image_id":image_id,
      "content":content,
      "font_id":font_id,
      "fontSize":fontSize,
      "fontCount":fontCount,
      "fontColor":fontColor,
      "rowSpacing":rowSpacing,
      "start_x":start_x,
      "start_y":start_y,
      "line":line,
      "type":type,
      "title":title,
    });
    return r.data;
  }
  static Future<List<MasterBean?>?> get_works() async {
    var a=await request(url: "master/get/", params:{
      "is_my_works":"false"
    });
    print(a.toString());
    return a.getTypedList<MasterBean>((map) => MasterBean.fromJson(map));
  }
  static Future<List<MasterBean?>?> get_my_works() async {
    var a=await request(url: "master/get/", params:{
      "is_my_works":"true"
    });
    return a.getTypedList<MasterBean>((map) => MasterBean.fromJson(map));
  }
  static delete_master(int id) async {
    var a=await request(url: "master/delete/", params:{
      "id":id
    });
    return a.toString();
  }
  static master_visible(int id,String visible) async {
    var a=await request(url: "master/visible/", params:{
      "id":id,
      "visible":visible,
    });
    return a.toString();
  }

  static validateToken() async {
    var a=await request(url: "user/validate_token/", params:{});
    if(a.data=="true"){
      return true;
    }else{
      return false;
    }
  }
}
